//
//  Date+Extension.swift
//  HuaYun
//
//  Created by enghou on 2018/7/26.
//  Copyright © 2018年 xyxorigation. All rights reserved.
//

import Foundation


let D_MINUTE: Double = 60

let D_HOUR: Double = 3600

let D_DAY: Double = 86400

let D_WEEK: Double = 604800

let D_YEAR: Double = 31556926

//let DATE_COMPONENTS =

let DATE_COMPOENTS = Set.init([Calendar.Component.year,Calendar.Component.month,Calendar.Component.day,Calendar.Component.weekOfYear,Calendar.Component.hour,Calendar.Component.minute,Calendar.Component.second,Calendar.Component.weekday,Calendar.Component.weekdayOrdinal])

let CURRENT_CALENDAR = Calendar.current

extension Date{
    
    func timeIntervalSince1970InMilliSecond() -> Double {
        
        return self.timeIntervalSince1970 * 1000
        
    }
    
    static func date(with timeIntervalInMilliSecondSince1970: Double)->Date{
        
        var timeInterval = timeIntervalInMilliSecondSince1970
        
        if timeIntervalInMilliSecondSince1970 > 140000000000 {
            
            timeInterval = timeIntervalInMilliSecondSince1970 / 1000
            
        }
        
        return Date(timeIntervalSince1970: timeInterval)
    }
    
    static func date(daysFromNow days: Int)->Date{
       
        return Date().date(byAddingDays:days)
    }
    
    static func date(beforeNow days: Int)->Date{
        return Date().date(subtractingDays:days)
    }
    
    static func date(hoursFromNow hours: Int)->Date{
        
        let aTimeInterval = Date().timeIntervalSinceReferenceDate + D_HOUR * Double(hours)
        
        return Date.init(timeIntervalSinceReferenceDate: aTimeInterval)
        
    }
    
    static func date(hoursBeforeNow hours: Int)->Date{
        
        let aTimeInterval = Date().timeIntervalSinceReferenceDate - D_HOUR * Double(hours)
        
        return Date.init(timeIntervalSinceReferenceDate: aTimeInterval)
        
    }
    
    static func date(minutesFromNow minutes: Int)->Date{
        
        let aTimeInterval = Date().timeIntervalSinceReferenceDate + D_MINUTE * Double(minutes)
        
        return Date.init(timeIntervalSinceReferenceDate: aTimeInterval)
        
    }
    
    static func date(minutesBeforeNow minutes: Int)->Date{
        
        let aTimeInterval = Date().timeIntervalSinceReferenceDate - D_MINUTE * Double(minutes)
        
        return Date.init(timeIntervalSinceReferenceDate: aTimeInterval)
        
    }
    
    func equalIgnoringTime(date: Date) -> Bool {
        
        let components1 = CURRENT_CALENDAR.dateComponents(DATE_COMPOENTS, from: self)
        
        let components2 = CURRENT_CALENDAR.dateComponents(DATE_COMPOENTS, from: date)
        
        return (components1.year == components2.year) && (components1.month == components2.month) && (components1.day == components2.day)
        
    }
    
    func isToday() -> Bool {
        return self.equalIgnoringTime(date: Date())
    }
    
    func isTomorrow()->Bool{
        
        return self.equalIgnoringTime(date: Date().date(byAddingDays: 1))
        
    }
    
    func isYesterDay()->Bool {
        
        return self.equalIgnoringTime(date: Date().date(subtractingDays: 1))
        
    }
    
    func date(subtractingDays days: Int) -> Date {
        return Date().addingTimeInterval(-TimeInterval.init(days * 3600 * 24))
    }

    func date(byAddingDays days: Int) -> Date {
        return Date().addingTimeInterval(TimeInterval.init(days * 3600 * 24))
    }
    
    static func date(with year: Int,month: Int,day: Int)->Date?{
        var component = DateComponents.init()
        let currentdate = Date()
        component.year = currentdate.year
        component.month = 1
        component.day = 1
        component.hour = 0
        component.minute = 0
        component.second = 0
        return component.date
    }
    
    var year: Int{
        
        get{
            return CURRENT_CALENDAR.dateComponents(DATE_COMPOENTS, from: self).year!
        }
    }
    
    var month: Int{
        
        get{
            return CURRENT_CALENDAR.dateComponents(DATE_COMPOENTS, from: self).month!
        }
    }
    
    var weekOfYear: Int{
        
        get{
            return CURRENT_CALENDAR.dateComponents(DATE_COMPOENTS, from: self).weekOfYear!
        }
    }
    
    var weekDay: Int{
        
        get{
            return CURRENT_CALENDAR.dateComponents(DATE_COMPOENTS, from: self).weekday!
        }
    }
    
    var weekOfMonth: Int{
        get{
            return CURRENT_CALENDAR.dateComponents(DATE_COMPOENTS, from: self).weekOfMonth!
        }
    }
    
    var day: Int{
        
        get{
            return CURRENT_CALENDAR.dateComponents(DATE_COMPOENTS, from: self).day!
        }
    }
    
    var hour: Int{
        
        get{
            return CURRENT_CALENDAR.dateComponents(DATE_COMPOENTS, from: self).hour!
        }
    }
    
    var minute: Int{
        
        get{
            return CURRENT_CALENDAR.dateComponents(DATE_COMPOENTS, from: self).minute!
        }
    }
    
    var tomorrow: Date{
        get{
            return Date.date(daysFromNow: 1)
        }
    }
    
    var yesterday: Date{
        get{
            return Date.date(beforeNow: 1)
        }
    }
    
    var dateStr: String{
        get{
            return self.dateStr(with: "yyyy-MM-dd HH:mm:ss")
        }
    }
    
    var dateLineStr: String{
        get{
            return self.dateStr(with: "yyyy-MM-dd")
        }
    }
    
    var dateOnlyYearMonth: String{
        get{
            return self.dateStr(with: "yyyy-MM")
        }
    }
    
    var monthday: String{
        get{
            return self.dateStr(with: "MM-dd")
        }
    }
    
    var dateYearMonthDay: String{
        get{
            return self.dateStr(with: "yyyy年MM月dd日")
        }
    }
    
    func dateStr(with format: String) -> String {
        if format.count == 0 {
            return ""
        }
        let formatter = DateFormatter.init()
        formatter.locale = Locale.init(identifier: "zh_CN")
        formatter.dateFormat = format
        let dateStr = formatter.string(from: self)
        return dateStr
    }
    
    
    
}
